﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Behavioral.Private;

namespace Behavioral
{
    public abstract class InitializerCollection : IInitializer<InitializationRunner>, IInitializationFluent
    {
        private ICollection<KeyValuePair<Type, object[]>> initializerTypes;

        protected InitializerCollection()
        {
            this.initializerTypes = new List<KeyValuePair<Type, object[]>>();
        }

        protected IInitializationFluent GivenThat<TInitializer>(params object[] args)
            where TInitializer : IInitializerMarker
        {
            this.initializerTypes.Add(new KeyValuePair<Type, object[]>(typeof (TInitializer), args));
            return this;
        }

        IInitializationFluent IInitializationFluent.And<TInitializer>(params object[] args)
        {
            GivenThat<TInitializer>(args);
            return this;
        }

        protected abstract void Register();

        void IInitializer<InitializationRunner>.SetUp(ref InitializationRunner runner)
        {
            Register();
            var unitTest = this.GetContext<IUnitTest>();
            foreach (KeyValuePair<Type, object[]> initializerType in this.initializerTypes)
            {
                var initializer = Activator.CreateInstance(initializerType.Key, initializerType.Value) as IInitializerMarker;
                var target = unitTest.Target;
                runner.SetUp(initializer, ref target);
                unitTest.Target = target;
            }
        }
    }
}
